home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / xview / segal / stats.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-23  |  7.9 KB  |  324 lines

  1.  
  2. /*  stats.c       Brian Tierney, LBL       8/90
  3.  *    for use with segal
  4.  *
  5.  *  These routines are used to compute statistics of objects in the mask image
  6.  */
  7.  
  8. #include "common.h"
  9.  
  10. char    **grid;
  11. long      size;            /* count of number of pixels in an object */
  12. double    pix_total;        /* sum of pixel values in an object */
  13. int       perim_count = 0;    /* count of number of pixels in the perimeter */
  14. int       min, max;        /* minimum and maximum pixel values in the
  15.                  * object */
  16. int       hist[256];        /* histogram array */
  17.  
  18.  
  19. /*************************************************************/
  20. void
  21. get_stats(i, j)
  22.     int       i, j;
  23. {
  24.     u_long standout();
  25.     void      get_object(), show_no_stats();
  26.     static int grid_rows = 0, grid_cols = 0;
  27.  
  28.     if (verbose)
  29.     fprintf(stderr, " \n show stats for object at loc %d,%d \n", i, j);
  30.  
  31.     XSetForeground(display, gc, standout(RED));
  32.     image_repaint_proc();
  33.  
  34.     bzero((char *) hist, 256 * sizeof(int));
  35.  
  36.     if (grid_rows != segal.rows || grid_cols != segal.cols) {    /* if size changes */
  37.     if (grid_rows != 0)    /* not 1st time */
  38.         free_2d_byte_array(grid);
  39.     grid = (char **) alloc_2d_byte_array(segal.rows, segal.cols);
  40.     grid_rows = segal.rows;
  41.     grid_cols = segal.cols;
  42.     }
  43.     get_object(j, i);
  44.  
  45.     if (grid != NULL)
  46.     bzero(*grid, segal.rows * segal.cols);
  47. }
  48.  
  49. /**************************************************************/
  50. void
  51. get_object(i, j)
  52.     int       i, j;
  53. {
  54.     static int tc = 0;
  55.     void      show_stats(), show_no_stats(), get_total_image_stats();
  56.  
  57.     size = 0L;
  58.     pix_total = 0.;
  59.     perim_count = 0;
  60.     min = 255;
  61.     max = 0;
  62.  
  63.     if (work_buf[i][j] > 0)
  64.     count_pixels(i, j);
  65.     else
  66.     get_total_image_stats();
  67.  
  68.     if (verbose)
  69.     fprintf(stdout, " size of object is %d pixels.\n", size);
  70.  
  71.     if (work_buf[i][j] > 0)
  72.     show_stats(i, j);
  73.     else {
  74. #ifdef NO_STATS
  75.     show_no_stats(i, j);
  76.     fprintf(stderr, " No object at this location. \n");
  77. #else
  78.     show_stats(-1, -1);
  79. #endif
  80.     }
  81. }
  82.  
  83. /*********************************************************************/
  84. void
  85. get_total_image_stats()
  86. {
  87.     register int i, j;
  88.  
  89.     size = segal.rows * segal.cols;
  90.  
  91.     for (i = 0; i < segal.rows; i++)
  92.     for (j = 0; j < segal.cols; j++) {
  93.         pix_total += (double) himage.data[i][j];
  94.         if (himage.data[i][j] > max)
  95.         max = himage.data[i][j];
  96.         if (himage.data[i][j] < min)
  97.         min = himage.data[i][j];
  98.         hist[himage.data[i][j]]++;
  99.     }
  100. }
  101.  
  102. /*********************************************************************/
  103. void
  104. show_stats(x, y)        /* display statistics */
  105.     int       x, y;
  106. {
  107.     double    p_ave;
  108.     int       median;
  109.     char      mesg[80];
  110.  
  111.     p_ave = pix_total / (double) size;
  112.     median = compute_median(size);
  113.  
  114.     if (verbose) {
  115.     fprintf(stdout, " total pixel intensity: %.0f, (log10: %.3f)\n",
  116.         pix_total, log10(pix_total));
  117.     fprintf(stdout, " mean pixel value: %.2f, (log10: %.3f)\n",
  118.         p_ave, log10(p_ave));
  119.     fprintf(stdout, " number of pixels in object perimeter: %d \n\n",
  120.         perim_count);
  121.     fprintf(stdout, " minimum pixel val: %d, maximum pixel val: %d\n\n",
  122.         min, max);
  123.     }
  124.     /* write into window */
  125.     if (x >= 0)
  126.     sprintf(mesg, "Object Location: (%d,%d)", x, y);
  127.     else
  128.     sprintf(mesg, "Statistics for entire image:");
  129.     (void) xv_set(segal_stats_win->stat_mess0,
  130.           PANEL_LABEL_STRING, mesg, NULL);
  131.  
  132.     sprintf(mesg, "Object size (pixels): %d", size);
  133.     (void) xv_set(segal_stats_win->stat_mess1,
  134.           PANEL_LABEL_STRING, mesg, NULL);
  135.  
  136.     sprintf(mesg, "Total pixel intensity:  %.0f, (log10: %.3f)",
  137.         pix_total, log10(pix_total));
  138.     (void) xv_set(segal_stats_win->stat_mess2,
  139.           PANEL_LABEL_STRING, mesg, NULL);
  140.  
  141.     sprintf(mesg, "Mean pixel value:  %.2f ",
  142.         p_ave);
  143.     (void) xv_set(segal_stats_win->stat_mess3,
  144.           PANEL_LABEL_STRING, mesg, NULL);
  145.  
  146.     sprintf(mesg, "Median pixel value: %d ", median);
  147.     (void) xv_set(segal_stats_win->stat_mess4,
  148.           PANEL_LABEL_STRING, mesg, NULL);
  149.  
  150.     if (x >= 0)
  151.     sprintf(mesg, "Number of pixels in object perimeter:  %d",
  152.         perim_count);
  153.     else
  154.     sprintf(mesg, " ");
  155.     (void) xv_set(segal_stats_win->stat_mess5,
  156.           PANEL_LABEL_STRING, mesg, NULL);
  157.  
  158.     sprintf(mesg, "Minimum: %d, Maximum: %d", min, max);
  159.     (void) xv_set(segal_stats_win->stat_mess6,
  160.           PANEL_LABEL_STRING, mesg, NULL);
  161.  
  162.     xv_set(segal_stats_win->stats_win, WIN_SHOW, TRUE, NULL);
  163. }
  164.  
  165. /*********************************************************************/
  166. void
  167. show_no_stats(x, y)        /* if object not found */
  168.     int       x, y;
  169. {
  170.     char      mesg[80];
  171.  
  172.     /* write into window */
  173.     sprintf(mesg, "Object Location: (%d,%d)", x, y);
  174.     (void) xv_set(segal_stats_win->stat_mess0,
  175.           PANEL_LABEL_STRING, mesg, NULL);
  176.  
  177.     sprintf(mesg, "No Object at this location");
  178.     (void) xv_set(segal_stats_win->stat_mess1,
  179.           PANEL_LABEL_STRING, mesg, NULL);
  180.  
  181.     sprintf(mesg, " ");
  182.     (void) xv_set(segal_stats_win->stat_mess2,
  183.           PANEL_LABEL_STRING, mesg, NULL);
  184.  
  185.     (void) xv_set(segal_stats_win->stat_mess3,
  186.           PANEL_LABEL_STRING, mesg, NULL);
  187.  
  188.     (void) xv_set(segal_stats_win->stat_mess4,
  189.           PANEL_LABEL_STRING, mesg, NULL);
  190.  
  191.     (void) xv_set(segal_stats_win->stat_mess5,
  192.           PANEL_LABEL_STRING, mesg, NULL);
  193.  
  194.     (void) xv_set(segal_stats_win->stat_mess6,
  195.           PANEL_LABEL_STRING, mesg, NULL);
  196.  
  197.     xv_set(segal_stats_win->stats_win, WIN_SHOW, TRUE, NULL);
  198. }
  199.  
  200. /*********************************************************************/
  201.  
  202. count_pixels(i, j)        /* recursive routine to count the number of
  203.                  * pixels in an object */
  204.     int       i, j;
  205. {
  206.     int       ii, jj;
  207.  
  208.     size++;
  209.     pix_total += (double) himage.data[i][j];
  210.     if (himage.data[i][j] > max)
  211.     max = himage.data[i][j];
  212.     if (himage.data[i][j] < min)
  213.     min = himage.data[i][j];
  214.     hist[himage.data[i][j]]++;
  215.  
  216.     grid[i][j] = 1;        /* mark is point as counted */
  217.  
  218.     XDrawPoint(display, view_xid, gc, j, i);
  219.  
  220.     if (num_neighbors(i, j) < 4) {    /* if has all 4 neigbors,not on
  221.                      * perimeter */
  222.     perim_count++;
  223.     }
  224.     ii = i + 1;
  225.     if (ii < segal.rows && grid[ii][j] == 0)
  226.     if (work_buf[ii][j] > 0)
  227.         count_pixels(ii, j);
  228.  
  229.     ii = i - 1;
  230.     if (ii > 0 && grid[ii][j] == 0)
  231.     if (work_buf[ii][j] > 0)
  232.         count_pixels(ii, j);
  233.  
  234.     jj = j + 1;
  235.     if (j + 1 < segal.cols && grid[i][jj] == 0)
  236.     if (work_buf[i][jj] > 0)
  237.         count_pixels(i, jj);
  238.  
  239.     jj = j - 1;
  240.     if (jj > 0 && grid[i][jj] == 0)
  241.     if (work_buf[i][jj] > 0)
  242.         count_pixels(i, jj);
  243.  
  244.     /* also check diagonals */
  245.     ii = i + 1;
  246.     jj = j + 1;
  247.     if (ii < segal.rows && jj < segal.cols && grid[ii][jj] == 0)
  248.     if (work_buf[ii][jj] > 0)
  249.         count_pixels(ii, jj);
  250.  
  251.     ii = i - 1;
  252.     jj = j - 1;
  253.     if (ii > 0 && jj > 0 && grid[ii][jj] == 0)
  254.     if (work_buf[ii][jj] > 0)
  255.         count_pixels(ii, jj);
  256.  
  257.     ii = i - 1;
  258.     jj = j + 1;
  259.     if (ii > 0 && j + 1 < segal.cols && grid[ii][jj] == 0)
  260.     if (work_buf[ii][jj] > 0)
  261.         count_pixels(ii, jj);
  262.  
  263.     ii = i + 1;
  264.     jj = j - 1;
  265.     if (i + 1 < segal.rows && jj > 0 && grid[ii][jj] == 0)
  266.     if (work_buf[ii][jj] > 0)
  267.         count_pixels(ii, jj);
  268.  
  269. }
  270.  
  271. /***********************************************************/
  272. int
  273. num_neighbors(i, j)        /* counts number of neighbors (max = 4) */
  274.     int
  275.               i, j;
  276. {
  277.     int       cnt = 0;
  278.  
  279.     if (i > 0)
  280.     if (work_buf[i - 1][j] > 0)
  281.         cnt++;
  282.     if (j > 0)
  283.     if (work_buf[i][j - 1] > 0)
  284.         cnt++;
  285.     if (i < segal.rows - 1)
  286.     if (work_buf[i + 1][j] > 0)
  287.         cnt++;
  288.     if (j < segal.cols - 1)
  289.     if (work_buf[i][j + 1] > 0)
  290.         cnt++;
  291.  
  292.     return (cnt);
  293. }
  294.  
  295. /*********************************************************** */
  296. int
  297. compute_median(npixels)
  298.     int       npixels;
  299. {
  300.     /*
  301.      * finds the gray level value at which 1/2 of the pixels in the window
  302.      * are below this value
  303.      */
  304.  
  305.     int       total = 0;    /* numb of pixels <= median */
  306.     int       mdn = 0;
  307.     int       half_count = npixels / 2;
  308.  
  309.     while (total + hist[mdn] <= half_count) {
  310.     total += hist[mdn];
  311.     mdn++;
  312.     }
  313.  
  314.     return (mdn);
  315. }
  316.  
  317. /*********************************************************** */
  318. void
  319. stat_close_proc()
  320. {                /* close button in stat window */
  321.  
  322.     xv_set(segal_stats_win->stats_win, WIN_SHOW, FALSE, NULL);
  323. }
  324.